Responsiveness and Size#

Controlling the responsiveness and size of a plot can be unintuitive.
This page tries to guide you through the basics of sizing configuration and it’s effect in different environments, to do that we need a frame of reference for what “size” means.

Let’s define two methods that will help us do just that:

import html
from io import StringIO

import panel as pn
import waloviz as wv

wv.extension()


def iframe(x, height=400):  # creates an HTML iframe with a certain height
    wv_html = StringIO()
    wv.save(x, wv_html)
    wv_html.seek(0)
    html_content = wv_html.read()
    escaped_html = html.escape(html_content)
    iframe_html = f'<iframe srcdoc="{escaped_html}" style="height:100%; width:100%" frameborder="0"></iframe>'
    return pn.pane.HTML(
        iframe_html,
        height=height,
        sizing_mode="stretch_width",
        styles={"background": "#3d8063"},
    )


def cell(x):  # displays normally
    return x

The iframe function tries to simulate the effects of putting our WaloViz player in an iframe (or a browser window for that matter), while the cell function just runs normally in the notebook.
These two situations may yield very different results in different configurations mostly because of their height, we’ll try to cover a few of the common differences in behavior.

Let’s start by showing how the iframe is different from the cell:

x = pn.widgets.StaticText(value="Hello!")
cell(x)
iframe(x)

As you can see the cell adjusts it’s height to fit the size of the content, in this case - the text “Hello!”
The iframe on the other hand colors a green area, this area is of a constant height (300 in the previous example), and a responsive width.
Now let’s see a simple WaloViz player in those two scenarios:

import numpy as np

noise = (np.random.randn(8000) / 100, 8000)
x = wv.Audio(noise, minimal=True)
cell(x)
iframe(x)
wv.save(x)
'wv.html'

As you can see, the results are very similar, but the cell has no margins while the iframe has some green margins on the bottom.
Try to change the width of the window (you can’t on mobile devices) and see how the player responsively scales to fit the width of the screen in both cases.

The default behavior of the WaloViz player is to scale the height and width to fit the container, while keeping the aspect ratio (width/height) at a constant, by default 3.5.

Let’s try to increase the aspect_ratio:

x = wv.Audio(noise, minimal=True, aspect_ratio=5.0)
cell(x)
iframe(x)

As you can see the player smaller in height when compared to its width, the width did not change because only the width is limited to a given maximum.

Again, try to change the width of the window to see the responsiveness of the width and height.
Now, let’s set a constant height value:

x = wv.Audio(noise, minimal=True, height=250)
cell(x)
iframe(x)

Try to change the width of the window, notice how this time only the width changes, the height stays constant.

Now let’s try to set a constant width:

x = wv.Audio(noise, minimal=True, width=600)
cell(x)
iframe(x)

Here there is a noticeable difference, why is that?
By setting the width or height, the aspect_ratio is disabled.

When we set the height to 250, the width was still responsive.
The same is true when we set the width to 600, the height is still responsive.

In the cell case, the height is minimized as much as possible, up to the minimum of WaloViz, this is the default behavior of jupyter notebooks.
In the iframe case, the height is resposive and adjusts itself to fit the maximum available height.

Let’s see one last case, where both width and height are fixed:

x = wv.Audio(noise, minimal=True, width=600, height=250)
cell(x)
iframe(x)

These are not responsive at all, but will remain static no matter what.

To make the player fill the entire container no matter what, you should use the sizing_mode="stretch_both" option:

x = wv.Audio(noise, minimal=True, sizing_mode="stretch_both")
cell(x)
iframe(x)
This web page was generated from a Jupyter notebook and not all interactivity will work on this website. Right click to download and run locally for full Python-backed interactivity.